#include "glare.d3d11.PixelShader.h"
#include "glare.d3d11.Driver.h"

namespace Glare {

	D3D11PixelShader::D3D11PixelShader(D3D11Driver* driver) 
		: _driver(driver)
		, _bytecode(NULL)
		, _d3d_pixel_shader(NULL)
	{

	}

	D3D11PixelShader::~D3D11PixelShader()
	{
		Unload();
	}

	bool D3D11PixelShader::Compile(const string& shader_code, string* errors, const string& profile, const string& entry_point)
	{
		*errors = "";
		Unload();

		ID3DBlob* err = NULL;
		string shader_profile = profile == "auto" ? "ps_5_0" : profile;
		D3DCompile(shader_code.c_str(), shader_code.length(), NULL, NULL, NULL, entry_point.c_str(), shader_profile.c_str(), 0, 0, &_bytecode, &err);

		if (err && errors)
		{
			char* buf = new char[err->GetBufferSize()];
			memcpy(buf, err->GetBufferPointer(), err->GetBufferSize());

			*errors = string(buf);
			delete[] buf;

			return false;
		}

		if (_bytecode)
		{
			GLARE_THROW(
				_driver->GetD3DDevice()->CreatePixelShader(_bytecode->GetBufferPointer(), _bytecode->GetBufferSize(), NULL, &_d3d_pixel_shader),
				"Error while creating D3D pixel shader");

			InitializeConstantBuffers(this, this);
			return true;
		}

		return false;
	}

	void D3D11PixelShader::Unload()
	{
		GLARE_SAFE_RELEASE(_bytecode, "Error while releasing D3D pixel shader bytecode");
		GLARE_SAFE_RELEASE(_d3d_pixel_shader, "Error while releasing D3D pixel shader");
	}

	Driver* D3D11PixelShader::GetDriver() const
	{
		return _driver;
	}

	ID3D11PixelShader* D3D11PixelShader::GetD3DPixelShader() const
	{
		return _d3d_pixel_shader;
	}

	ID3DBlob* D3D11PixelShader::GetD3DByteCode() const
	{
		return _bytecode;
	}
}
